package com.dlc.commonlibrary.ble;

import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.text.TextUtils;
import android.widget.Toast;
import com.dlc.commonlibrary.utils.LogPlus;
import com.tbruyelle.rxpermissions.RxPermissions;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;


/**
 * Created by Administrator on 2017/7/25.
 */

public class BleHelper {


    public static final int REQUEST_ENABLE_BT = 3;

    public static  BluetoothSocket bTSocket;//连接套接字
    public static  BluetoothAdapter bTAdapter;//蓝牙适配器
    public static InputStream inStream;//输入流
    public static OutputStream outStream;//输出流
    public static ReadBleThread readBleThread;
    public static BleCallBack callBack;
    public static BluetoothDevice mDevice;//已经连接的设备


    public static BleHelper mInstance;





    private BleHelper() {
        mInstance = this;
    }

    public static BleHelper getInstance(){
        if(mInstance == null){
            mInstance = new BleHelper();
        }

        return mInstance;
    }


    /**
     * 蓝牙获取数据回调
     */
    public static  interface  BleCallBack{

        public void readDatas(String data);

    }

    /**
     * 发现设备回调
     */
    public static interface  BleFindDeviceCall{
        //搜索设备
        public void findDevice(BluetoothDevice device);
    }

    /**
     * 连接回调
     */
    public static interface  BleConnectCall{
        public void connectCall(boolean isSuccess);
    }
    /**
     * 读线程
     */
    private class  ReadBleThread extends Thread{
        private boolean isStop = false;

        public ReadBleThread() {
            this.start();
        }


        /**
         * 关闭读线程
         */
        public void stopThread(){
            isStop = true;
        }

        /**
         * 关闭输入量
         */
        private void close(){
            if(inStream != null){
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }


        @Override
        public void run() {
            super.run();
            while (!isStop) {
                if(inStream != null){
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    try {
                        while( (len=inStream.read(buffer)) != -1){
                            String ss= new String(buffer, 0, len, "utf-8");
                            if(callBack != null){
                                callBack.readDatas(ss);
                            }
                            sleep(5);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }

            close();

        }

    }


    /**
     * 返回蓝牙是否打开
     * @return
     */
    public boolean bleEnable(){
        if(BluetoothAdapter.getDefaultAdapter() == null){
            return false;
        } else if(!bTAdapter.isEnabled()){
            return false;
        } else {
            return true;
        }
    }

    /**
     * 自动连接蓝牙
     * @param address
     * @param call
     */
    public void autoConnect(String address,BleConnectCall call){
        bTAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bTAdapter != null) {
            if (bTAdapter.isEnabled()) {
               connectBle(address,call);
            }
        }
    }
    /**
     * 检查蓝牙
     */
    public  void checkBT(Context context,BleFindDeviceCall call) {
        bTAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bTAdapter != null) {
            if (!bTAdapter.isEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                // 设置蓝牙可见性，最多300秒
                intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                Activity activity = (Activity) context;
                activity.startActivityForResult(intent,REQUEST_ENABLE_BT);
            } else {

                findDevice(call);
                getPermission(context);
            }
        } else {
            Toast.makeText(context,"本地设备驱动异常!",Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 检查蓝牙
     */
    public  void checkBT(Context context) {
        bTAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bTAdapter != null) {
            if (!bTAdapter.isEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                // 设置蓝牙可见性，最多300秒
                intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                Activity activity = (Activity) context;
                activity.startActivityForResult(intent,REQUEST_ENABLE_BT);
            } else {
                getPermission(context);
            }
        } else {
            Toast.makeText(context,"本地设备驱动异常!",Toast.LENGTH_SHORT).show();
        }
    }

    public   void getPermission(final Context context){
        RxPermissions rxPermissions = new RxPermissions((Activity) context);
        rxPermissions.request(Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.BLUETOOTH,Manifest.permission.BLUETOOTH_ADMIN)
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                        if (aBoolean) {
                            //用户同意使用write权限
                            if(bTAdapter.isDiscovering()){
                                bTAdapter.cancelDiscovery();
                            }
                           boolean success =  bTAdapter.startDiscovery();
                            LogPlus.e("startDiscovery:"+success);
                        }else {
                            Toast.makeText(context,"用户拒绝使用权限",Toast.LENGTH_SHORT).show();
                        }
                    }
                });

    }


    private void findDevice(BleFindDeviceCall call){
        Set<BluetoothDevice> pairedDevices = bTAdapter.getBondedDevices();
// If there are paired devices
        if (pairedDevices.size() > 0) {
            // Loop through paired devices
            for (BluetoothDevice btDevice : pairedDevices) {
                if(call != null){
                    call.findDevice(btDevice);
                }
//                // Add the name and address to an array adapter to show in a ListView
//                Log.e("getBondedDevices",btDevice.getName() + "\n" + btDevice.getAddress());
//                if(btDevice.getName().contains( BleConstant.RFID_DEVICE_NAME)){
//                    connectBle(btDevice.getAddress());
//                }
            }
        }
    }

    /**|
     * 连接设备
     * @param address
     */
    public void  connectBle(final String address, final BleConnectCall connectCall){
        Observable.unsafeCreate(new Observable.OnSubscribe<Boolean>() {

            @Override
            public void call(Subscriber<? super Boolean> subscriber) {
                //获取远方设备

                mDevice = bTAdapter.getRemoteDevice(address);
                try {
                    //连接获取socket
                    bTSocket = mDevice.createRfcommSocketToServiceRecord(BleConstant.BLE_UUID);
                    bTSocket.connect();
                    //获取输入流
                    inStream = bTSocket.getInputStream();

                    //获取输出流
                    outStream = bTSocket.getOutputStream();
                    write(BleConstant.API_END_READ);
                    //代表连接成功
                    subscriber.onNext(true);
                    subscriber.onCompleted();

                    //开启读线程
                } catch (IOException e) {
                    subscriber.onNext(false);
                    subscriber.onCompleted();

                }
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                        if(connectCall != null){
                            connectCall.connectCall(aBoolean.booleanValue());
                        }
                    }
                });

    }


    /**
     * 读数据
     * @param c
     */
    public void  readValue(BleCallBack c){
        callBack = c;
        if(readBleThread != null){
            readBleThread.stopThread();
        }

        readBleThread = new ReadBleThread();

    }

    /**
     * 写数据
     * @param outByte
     */
    public void write(String  outByte ){
        try {
            if(!TextUtils.isEmpty(outByte))
                LogPlus.e("Ble write:"+outByte);
                outStream.write(outByte.getBytes());
        }catch (Exception e){

        }
    }
    /**
     * 写数据
     * @param outByte
     */
    public void write(byte  outByte ){
        try {
                outStream.write(outByte);
        }catch (Exception e){

        }
    }

    public void write(byte[]  outByte ){
        try {
            outStream.write(outByte);
        }catch (Exception e){

        }
    }

    /**
     * 设置功率
     * @param attenuation
     */
    public void setAttenuation(int attenuation){
        String cmdString = String.format(">x p %d\r", attenuation);
        write(cmdString);
    }


    /**
     * 停止读数据
     */
    public void stopReadValue(){
        if(readBleThread != null){
            readBleThread.stopThread();
        }
    }

    /**
     * 只报告新的标签
     */
    public void swing_setAllTagReport(boolean on_all_tag_report) {
        String cmdString = ">x b ";

        if (on_all_tag_report) {
            cmdString += "1\r";
        } else {
            cmdString += "0\r";
        }

        byte[] pkt = cmdString.getBytes();
        write(pkt);
    }

    /**
     * 获取缓存在手持机的数据
     */
    public void swing_getBuffer() {
        String cmdString = ">y t\r";
        byte[] pkt = cmdString.getBytes();
        write(pkt);
    }


    /**
     * 关闭ble
     */
    public void stopBle(){
        if(bTSocket != null){
            try {
                bTSocket.close();
                mDevice = null;
                if (bTAdapter != null) {
                    bTAdapter.disable();
                }
                bTAdapter = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 关闭ble
     */
    public void stopDevice(){
        mDevice = null;
    }
    /**
     * 获取连接的设备
     * @return
     */
    public BluetoothDevice getConnectDevice(){
        return mDevice;
    }



    //提供以下方法读写

    /**
     * 读写手持机
     * @param attenuation
     */
    public void startReadDevice(final int attenuation){
        //停止读
        write(BleConstant.API_END_READ);
        swing_setAllTagReport(false);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //设置功率
                setAttenuation(attenuation);
                //清除个数
                write(BleConstant.API_CLEAN_COUNT);
                //开始读
                write(BleConstant.API_START_READ);
            }
        },500);

    }

    /**
     * String类型变量是否可以转换数字类型
     * @param str
     * @return
     */
    public boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if( !isNum.matches() ){
            return false;
        }
        return true;
    }


}
